package com.example.everying.utils;

import com.example.everying.model.entity.user.PointsTransaction;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: everything
 * @description: 连续签到工具类
 * @author: zw
 * @create: 2025-08-02 10:45
 **/

public class SignUtils {
    // 计算用户当前连续签到天数
    public static int calculateContinuousDays(String userId, List<PointsTransaction> allTransactions) {
        LocalDate today = LocalDate.now();

        // 1. 过滤并排序当前用户的签到记录（严格校验）
        List<PointsTransaction> signTransactions = allTransactions.stream()
                .filter(t -> userId.equals(t.getUserId())
                        && t.getDescription() != null
                        && t.getDescription().contains("签到"))
                .sorted(Comparator.comparing(PointsTransaction::getCreateTime))
                .collect(Collectors.toList());

        // 边界情况1：无签到记录 → 返回0（符合业务常识）
        if (signTransactions.isEmpty()) {
            return 0;
        }

        // 边界情况2：仅1条签到记录 → 单独处理，直接返回结果（不进入后续逻辑）
        if (signTransactions.size() == 1) {
            LocalDate signDay = signTransactions.get(0).getCreateTime().toLocalDate();
            long daysSinceSign = ChronoUnit.DAYS.between(signDay, today);

            if (signDay.equals(today)) {
                return 1; // 今日签到：连续1天
            } else if (daysSinceSign == 1) {
                return 2; // 间隔1天（昨日签到，今日未签）：按业务需求返回2
            } else {
                return 1; // 间隔≥2天：返回1（历史签到1天）
            }
        }

        // 3. 多条记录：执行循环计算连续天数（仅处理签到记录间的连续性）
        int continuousDays = 1;
        LocalDate lastSignDay = signTransactions.get(0).getCreateTime().toLocalDate();

        for (int i = 1; i < signTransactions.size(); i++) {
            LocalDate currentSignDay = signTransactions.get(i).getCreateTime().toLocalDate();
            long daysBetween = ChronoUnit.DAYS.between(lastSignDay, currentSignDay);

            if (daysBetween == 1) {
                // 连续签到（间隔1天）：累加
                continuousDays++;
            } else if (daysBetween > 1) {
                // 断签（间隔≥2天）：重置为1
                continuousDays = 1;
            }
            // 间隔0天（同一天重复签到）：不累加，保持原天数
            lastSignDay = currentSignDay;
        }

        // 4. 多条记录场景：结合最后一次签到与今日的关系，调整最终结果
        LocalDate latestSignDay = signTransactions.get(signTransactions.size() - 1).getCreateTime().toLocalDate();
        long daysFromLatestToToday = ChronoUnit.DAYS.between(latestSignDay, today);

        if (!latestSignDay.equals(today)) {
            // 今日未签到
            if (daysFromLatestToToday >= 2) {
                return 1; // 间隔≥2天：断签，返回1
            } else {
                return continuousDays + 1; // 间隔1天：保持循环计算结果
            }
        }

        // 今日已签到：确保结果至少为1（覆盖断签后今日签到的场景）
        return Math.max(continuousDays, 1);
    }

    /**
     * public static int calculateContinuousDays(String userId, List<PointsTransaction> allTransactions) {
     *         LocalDate today = LocalDate.now();
     *         int continuousDays = 0;
     *
     *         // 1. 过滤当前用户的签到交易（严格校验）
     *         List<PointsTransaction> signTransactions = allTransactions.stream()
     *                 .filter(t -> t.getUserId().equals(userId) // 确保是当前用户
     *                         && t.getDescription() != null
     *                         && t.getDescription().contains("签到"))
     *                 .sorted(Comparator.comparing(PointsTransaction::getCreateTime)) // 按签到时间正序排列
     *                 .collect(Collectors.toList());
     *
     *         if (signTransactions.isEmpty()) {
     *             return 1; // 无签到记录，连续天数为0
     *         }
     *
     *         // 2. 遍历计算连续天数（仅判断【昨日是否未签到】来断签）
     *         LocalDate lastSignDay = signTransactions.get(0).getCreateTime().toLocalDate();
     *         continuousDays = 1; // 至少1天（有签到记录）
     *
     *         for (int i = 1; i < signTransactions.size(); i++) {
     *             LocalDate currentSignDay = signTransactions.get(i).getCreateTime().toLocalDate();
     *             long  daysBetween = ChronoUnit.DAYS.between(currentSignDay, lastSignDay);
     *
     *             if (daysBetween >= 2) {
     *                 continuousDays = 1; // 间隔2天（中间1天未签）→ 连续天数=2
     *             } else if (daysBetween == 0) {
     *                 continuousDays++; // 间隔≥3天（中间≥2天未签）→ 断签重置为1
     *             } else {
     *                 continuousDays ++; // 间隔≤1天→正常累加
     *             }
     *             lastSignDay = currentSignDay;
     *         }
     *
     *         // 单条记录时，无需循环，直接返回1（或根据今日是否签到调整）
     *         if (signTransactions.size() == 1) {
     *             LocalDate latestSignDay = signTransactions.get(0).getCreateTime().toLocalDate();
     *             // 计算最后签到日到今天的间隔天数
     *             long daysSinceLastSign = ChronoUnit.DAYS.between(latestSignDay, today);
     *             if (latestSignDay.equals(today)) {
     *                 return 1; // 今日签到，连续1天
     *             } else if (daysSinceLastSign == 1) {
     *                 // 第二天未签到（间隔1天）：返回2（业务需求）
     *                 return 2;
     *             }else {
     *                 return 1; // 历史签到1天，今日未签，保持1天（按业务需求调整）
     *             }
     *         }
     *
     *         // 3. 校验今日是否签到，不影响断签逻辑（仅更新连续天数显示）
     *         LocalDate latestSignDay = signTransactions.get(signTransactions.size() - 1).getCreateTime().toLocalDate();
     *         long daysBetween = ChronoUnit.DAYS.between(latestSignDay, today); // 计算间隔天数
     *         if (!latestSignDay.equals(today)) {
     *             // 今日未签到的场景
     *             if (daysBetween >= 2) {
     *                 // 间隔正好2天 → 强制返回1
     *                 return 1;
     *             } else {
     *                 // 其他间隔天数 → 保持原有计算结果
     *                 return continuousDays;
     *             }
     *         }
     *
     *         // 今日有签到 → 连续天数至少为1（覆盖断签后今日签到）
     *         return Math.max(continuousDays, 1);
     *     }
     */
}
